home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume15 / ggems / part03 < prev    next >
Encoding:
Text File  |  1990-10-14  |  53.5 KB  |  1,997 lines

  1. Newsgroups: comp.sources.misc
  2. X-UNIX-From: craig@weedeater.math.yale.edu
  3. subject: v15i025: Graphics Gems, Part 3/5
  4. from: Craig Kolb <craig@weedeater.math.yale.edu>
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 15, Issue 25
  8. Submitted-by: Craig Kolb <craig@weedeater.math.yale.edu>
  9. Archive-name: ggems/part03
  10.  
  11. #! /bin/sh
  12. # This is a shell archive.  Remove anything before this line, then unpack
  13. # it by saving it into a file and typing "sh file".  To overwrite existing
  14. # files, type "sh file -c".  You can also feed this as standard input via
  15. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  16. # will see the following message at the end:
  17. #        "End of archive 3 (of 5)."
  18. # Contents:  AALines/utah.c Albers.c BoundSphere.c Dissolve.c
  19. #   DoubleLine.c GraphicsGems.h LineEdge.c MatrixInvert.c
  20. #   PolyScan/poly_clip.c PolyScan/poly_scan.c Roots3And4.c
  21. # Wrapped by craig@weedeater on Fri Oct 12 15:53:13 1990
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'AALines/utah.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'AALines/utah.c'\"
  25. else
  26. echo shar: Extracting \"'AALines/utah.c'\" \(4532 characters\)
  27. sed "s/^X//" >'AALines/utah.c' <<'END_OF_FILE'
  28. X/*
  29. X    file:        utah.c
  30. X    description:    interface to Utah RLE toolkit
  31. X    author:        A. T. Campbell
  32. X    date:        October 27, 1989
  33. X*/
  34. X
  35. X#ifndef lint
  36. Xstatic char    sccsid[] = "%W% %G%";        /* SCCS info */
  37. X#endif lint
  38. X    
  39. X#include <math.h>
  40. X#include <stdio.h>
  41. X#ifdef sequent
  42. X#include <strings.h>
  43. X#else
  44. X#include <string.h>
  45. X#endif
  46. X#include "utah.h"
  47. X
  48. X/******************************************************************************/
  49. X
  50. X/* return values */
  51. Xextern void    free();
  52. Xextern char    *malloc();
  53. X
  54. X/******************************************************************************/
  55. X
  56. Xutah_read_close(ufp)
  57. XUTAH_FILE    *ufp;
  58. X{
  59. X    return(0);
  60. X}
  61. X
  62. X/******************************************************************************/
  63. X
  64. XUTAH_FILE *
  65. Xutah_read_init(fname, ht, wd)
  66. X
  67. Xchar    *fname;
  68. Xint    *ht, *wd;
  69. X{
  70. X    FILE        *fp;
  71. X    UTAH_FILE    *ufp;
  72. X
  73. X    /* open output stream */
  74. X    if (!strcmp(fname, ""))
  75. X        fp = stdin;
  76. X    else {
  77. X        if ((fp = fopen(fname, "r")) == NULL)
  78. X        return(NULL);
  79. X    }
  80. X
  81. X     /* change the default sv_globals struct to match what we need */
  82. X    ufp = (UTAH_FILE *) malloc(sizeof(UTAH_FILE));
  83. X    *ufp = sv_globals;
  84. X    ufp->svfb_fd = fp;
  85. X
  86. X    /* read the header in the input file */
  87. X      if (rle_get_setup(ufp) != 0)
  88. X        return(NULL);
  89. X
  90. X    /* get image size */
  91. X    *wd = ufp->sv_xmax - ufp->sv_xmin + 1;
  92. X    *ht = ufp->sv_ymax - ufp->sv_ymin + 1;
  93. X
  94. X    /* normal termination */
  95. X    return(ufp);
  96. X}
  97. X
  98. X/******************************************************************************/
  99. X
  100. Xutah_read_pixels(ufp, pixels)
  101. X
  102. XUTAH_FILE     *ufp;
  103. Xunsigned char    pixels[][3];
  104. X{
  105. X    static unsigned    n = 0;
  106. X    static unsigned char    *r = NULL, *g = NULL, *b = NULL;
  107. X    int        i, width;
  108. X
  109. X    /* allocate storage */
  110. X    width = ufp->sv_xmax + 1;
  111. X    if (width > n) {
  112. X        if (n > 0) {
  113. X            free((char *)r);
  114. X            free((char *)g);
  115. X            free((char *)b);
  116. X        }
  117. X        n = width;
  118. X        r = (unsigned char *) malloc(n * sizeof(unsigned char));
  119. X        g = (unsigned char *) malloc(n * sizeof(unsigned char));
  120. X        b = (unsigned char *) malloc(n * sizeof(unsigned char));
  121. X    }
  122. X
  123. X    /* read this row */
  124. X    utah_read_rgb(ufp, r, g, b);
  125. X
  126. X    /* convert to pixels */
  127. X    for (i = 0; i < width; i++) {
  128. X        pixels[i][0] = r[i];
  129. X        pixels[i][1] = g[i];
  130. X        pixels[i][2] = b[i];
  131. X    }
  132. X
  133. X    return(0);
  134. X}
  135. X
  136. X/******************************************************************************/
  137. X
  138. Xutah_read_rgb(ufp, r, g, b)
  139. X
  140. XUTAH_FILE    *ufp;
  141. Xunsigned char    r[], g[], b[];
  142. X{
  143. X    rle_pixel    *rows[3];
  144. X
  145. X    /* set color channels */
  146. X    rows[0] = r;
  147. X    rows[1] = g;
  148. X    rows[2] = b;
  149. X
  150. X    /* read this row */
  151. X    rle_getrow(ufp, rows);
  152. X    return(0);
  153. X}
  154. X
  155. X/******************************************************************************/
  156. X
  157. Xutah_write_close(ufp)
  158. X
  159. XUTAH_FILE    *ufp;
  160. X{
  161. X    if (!ufp) return(-1);
  162. X    sv_puteof(ufp);
  163. X    return(0);
  164. X}
  165. X
  166. X/******************************************************************************/
  167. X
  168. XUTAH_FILE *
  169. Xutah_write_init(fname, ht, wd)
  170. X
  171. Xchar    *fname;
  172. Xint    ht, wd;
  173. X{
  174. X    FILE        *fp;
  175. X    UTAH_FILE    *ufp;
  176. X
  177. X    /* open output stream */
  178. X    if (!strcmp(fname, ""))
  179. X        fp = stdout;
  180. X    else {
  181. X        if ((fp = fopen(fname, "w")) == NULL)
  182. X        return(NULL);
  183. X    }
  184. X
  185. X     /* change the default sv_globals struct to match what we need */
  186. X    ufp = (UTAH_FILE *) malloc(sizeof(UTAH_FILE));
  187. X    *ufp = sv_globals;
  188. X    ufp->svfb_fd = fp;
  189. X    ufp->sv_xmax = wd - 1;
  190. X    ufp->sv_ymax = ht - 1;
  191. X    ufp->sv_alpha = 0;    /* No coverage (alpha) */
  192. X
  193. X    /* create the header in the output file */
  194. X      sv_setup(RUN_DISPATCH, ufp);
  195. X
  196. X    /* normal termination */
  197. X    return(ufp);
  198. X}
  199. X
  200. X/******************************************************************************/
  201. X
  202. Xutah_write_pixels(ufp, pixels)
  203. X
  204. XUTAH_FILE    *ufp;
  205. Xunsigned char    pixels[][3];
  206. X{
  207. X    static unsigned    n = 0;
  208. X    static unsigned char    *r = NULL, *g = NULL, *b = NULL;
  209. X    int        i, width;
  210. X
  211. X    /* allocate storage */
  212. X    width = ufp->sv_xmax + 1;
  213. X    if (width > n) {
  214. X        if (n > 0) {
  215. X            free((char *)r);
  216. X            free((char *)g);
  217. X            free((char *)b);
  218. X        }
  219. X        n = width;
  220. X        r = (unsigned char *) malloc(n * sizeof(unsigned char));
  221. X        g = (unsigned char *) malloc(n * sizeof(unsigned char));
  222. X        b = (unsigned char *) malloc(n * sizeof(unsigned char));
  223. X    }
  224. X
  225. X    /* convert to color channels */
  226. X    for (i = 0; i < width; i++) {
  227. X        r[i] = pixels[i][0];
  228. X        g[i] = pixels[i][1];
  229. X        b[i] = pixels[i][2];
  230. X    }
  231. X
  232. X    /* write this row */
  233. X    utah_write_rgb(ufp, r, g, b);
  234. X    return(0);
  235. X}
  236. X
  237. X/******************************************************************************/
  238. X
  239. Xutah_write_rgb(ufp, r, g, b)
  240. X
  241. XUTAH_FILE    *ufp;
  242. Xunsigned char    r[], g[], b[];
  243. X{
  244. X    rle_pixel    *rows[3];
  245. X    int        width;
  246. X
  247. X    /* set color channels */
  248. X    rows[0] = r;
  249. X    rows[1] = g;
  250. X    rows[2] = b;
  251. X
  252. X    /* write this row */
  253. X    width = ufp->sv_xmax - ufp->sv_xmin + 1;
  254. X    sv_putrow(rows, width, ufp);
  255. X    return(0);
  256. X}
  257. X
  258. X/******************************************************************************/
  259. END_OF_FILE
  260. if test 4532 -ne `wc -c <'AALines/utah.c'`; then
  261.     echo shar: \"'AALines/utah.c'\" unpacked with wrong size!
  262. fi
  263. # end of 'AALines/utah.c'
  264. fi
  265. if test -f 'Albers.c' -a "${1}" != "-c" ; then 
  266.   echo shar: Will not clobber existing file \"'Albers.c'\"
  267. else
  268. echo shar: Extracting \"'Albers.c'\" \(3994 characters\)
  269. sed "s/^X//" >'Albers.c' <<'END_OF_FILE'
  270. X/*
  271. XAlbers Equal-Area Conic Map Projection
  272. Xby Paul Bame
  273. Xfrom "Graphics Gems", Academic Press, 1990
  274. X*/
  275. X
  276. X/*
  277. X * Albers Conic Equal-Area Projection
  278. X * Formulae taken from "Map Projections Used by the U.S. 
  279. X * Geological Survey" Bulletin #1532
  280. X *
  281. X * Equation reference numbers and some variable names taken
  282. X * from the reference.
  283. X * To use, call albers setup() once and then albers_project()
  284. X * for each coordinate pair of interest.
  285. X*/
  286. X
  287. X#include "GraphicsGems.h"        
  288. X#include <stdio.h>
  289. X#include <math.h>
  290. X
  291. X/*
  292. X * This is the Clarke 1866 Earth spheroid data which is often
  293. X * used by the USGS - there are other spheroids however - see the
  294. X * book.
  295. X */
  296. X/*
  297. X * Earth radii in different units */
  298. X#define CONST_EradiusKM (6378.2064)     /* Kilometers */
  299. X#define CONST_EradiusMI (CONST_EradiusKM/1.609)    /* Miles */
  300. X#define CONST_Ec        (0.082271854)    /* Eccentricity */
  301. X#define CONST_Ecsq    (0.006768658)    /* Eccentricity squared */
  302. X
  303. X
  304. X
  305. X/*
  306. X * To keep things simple, assume Earth radius is 1.0. Projected
  307. X * coordinates (X and Y obtained from albers project ()) are
  308. X *  dimensionless and may be multiplied by any desired radius
  309. X *  to convert to desired units (usually Kilometers or Miles).
  310. X*/
  311. X#define CONST_Eradius 1.0
  312. X
  313. X/* Pre-computed variables */
  314. Xstatic double middlelon;        /* longitude at center of map */
  315. Xstatic double bigC, cone_const, r0;    /* See the reference */
  316. X
  317. Xstatic
  318. Xcalc_q_msq(lat, qp, msqp)
  319. Xdouble lat;
  320. Xdouble *qp;
  321. Xdouble *msqp;
  322. X/*
  323. X * Given latitude, calculate 'q' [eq 3-12] 
  324. X * if msqp is != NULL, m^2  [eq. 12-15].
  325. X*/
  326. X{
  327. X    double s, c, es;
  328. X
  329. X    s = sin(lat);
  330. X    es = s * CONST_Ec;
  331. X
  332. X    *qp = (1.0 - CONST_Ecsq) * ((s / (1 - es * es))-
  333. X        (1 / (2 * CONST_Ec)) * log((1 - es) / (1 + es)));
  334. X
  335. X    if (msqp != NULL)
  336. X    {
  337. X        c = cos(lat);
  338. X        *msqp = c * c/ (1 - es * es);
  339. X    }
  340. X}
  341. X
  342. X
  343. X
  344. X
  345. Xalbers_setup(southlat, northlat, originlon, originlat)
  346. Xdouble southlat, northlat;
  347. Xdouble originlon;
  348. Xdouble originlat;
  349. X/*
  350. X * Pre-compute a bunch of variables which are used by the 
  351. X * albers_project()
  352. X *
  353. X * southlat     Southern latitude for Albers projection
  354. X * northlat    Northern latitute for Albers projection
  355. X * originlon    Longitude for origin of projected map
  356. X * originlat    Latitude for origin of projected map -
  357. X *                often (northlat + southlat) / 2
  358. X*/
  359. X{
  360. X    double q1, q2, q0;
  361. X    double m1sq, m2sq;
  362. X
  363. X    middlelon = originlon;
  364. X    
  365. X    cal_q_msq(southlat, &q1, &m1sq);
  366. X    cal_q_msq(northlat, &q2, &m2sq);
  367. X    cal_q_msq(originlat, &q0, NULL);
  368. X
  369. X    cone_const = (m1sq - m2sq) / (q2 - q1);
  370. X    bigC = m1sq + cone_const * q1;
  371. X    r0 = CONST_Eradius * sqrt(bigC - cone_const *q0) / cone_const;
  372. X}
  373. X
  374. X/***************************************************************/
  375. X
  376. Xalbers_project(lon, lat, xp, yp)
  377. Xdouble lon, lat;
  378. Xdouble *xp, *yp;
  379. X/*
  380. X * Project lon/lat (in radians) according to albers_setup and 
  381. X * return the results via xp, yp. Units of *xp and *yp are same
  382. X * as the units used by CONST_Eradius.
  383. X*/
  384. X{
  385. X    double q, r, theta;
  386. X    calc_q_msq(lat, &q, NULL);
  387. X    theta = cone_const * (lon -middlelon);
  388. X    r = CONST_Eradius * sqrt(bigC - cone_const * q) / cone_const;
  389. X    *xp = r * sin(theta);
  390. X    *yp = r0 - r * cos(theta);
  391. X}
  392. X
  393. X#ifdef TESTPROGRAM
  394. X
  395. X/*
  396. X * Test value from the USGS book. Because of roundoff, the 
  397. X * actual values are printed for visual inspection rather 
  398. X * than guessing what constitutes "close enough".
  399. X*/
  400. X/* Convert a degress, minutes pair to radians */
  401. X#define DEG_MIN2RAD(degrees, minutes) \
  402. X    ((double) ((degrees + minutes / 60.0) * M_PI / 180.0))
  403. X
  404. X#define Nlat DEG_MIN2RAD(29, 30)    /* 29 degrees, 30' North Lat */
  405. X#define Slat DEG_MIN2RAD(45, 30)    
  406. X#define Originlat DEG_MIN2RAD(23, 0)    
  407. X#define Originlon DEG_MIN2RAD(-96, 0) /* West longitude is negative */
  408. X
  409. X#define Testlat DEG_MIN2RAD(35, 0)
  410. X#define Testlon DEG_MIN2RAD(-75, 0)
  411. X
  412. X#define TestX 1885.4727
  413. X#define TestY 1535.9250
  414. X
  415. Xmain()
  416. X{
  417. X    int i;
  418. X    double x, y;
  419. X
  420. X/* Setup is also from USGS book test set */
  421. X    albers_setup(Slat, Nlat, Originlon, Originlat);
  422. X
  423. X    albers_project(Testlon, Testlat, &x, &y);
  424. X    printf("%.41f, %.41f =?= %.41f, %.41f/n",
  425. X        x * CONST_EradiusKM, y * CONST_EradiusKM,
  426. X        TestX, TestY);
  427. X}
  428. X#endif        /* TESTPROGRAM */
  429. END_OF_FILE
  430. if test 3994 -ne `wc -c <'Albers.c'`; then
  431.     echo shar: \"'Albers.c'\" unpacked with wrong size!
  432. fi
  433. # end of 'Albers.c'
  434. fi
  435. if test -f 'BoundSphere.c' -a "${1}" != "-c" ; then 
  436.   echo shar: Will not clobber existing file \"'BoundSphere.c'\"
  437. else
  438. echo shar: Extracting \"'BoundSphere.c'\" \(3767 characters\)
  439. sed "s/^X//" >'BoundSphere.c' <<'END_OF_FILE'
  440. X/*
  441. XAn Efficient Bounding Sphere
  442. Xby Jack Ritter
  443. Xfrom "Graphics Gems", Academic Press, 1990
  444. X*/
  445. X
  446. X/* Routine to calculate tight bounding sphere over    */
  447. X/* a set of points in 3D */
  448. X/* This contains the routine find_bounding_sphere(), */
  449. X/* the struct definition, and the globals used for parameters. */
  450. X/* The abs() of all coordinates must be < BIGNUMBER */
  451. X/* Code written by Jack Ritter and Lyle Rains. */
  452. X
  453. X#include <stdio.h>
  454. X#include <math.h>
  455. X#include "GraphicsGems.h"
  456. X
  457. X#define BIGNUMBER 100000000.0          /* hundred million */
  458. X
  459. X/* GLOBALS. These are used as input and output parameters. */
  460. Xstruct Point3Struct caller_p,cen;
  461. Xdouble rad;
  462. Xint NUM_POINTS;
  463. X
  464. X/* Call with no parameters. Caller must set NUM_POINTS */
  465. X/* before calling. */
  466. X/* Caller must supply the routine GET_iTH_POINT(i), which loads his */
  467. X/* ith point into the global struct caller_p. (0 <= i < NUM_POINTS). */
  468. X/* The calling order of the points is irrelevant. */
  469. X/* The final bounding sphere will be put into the globals */
  470. X/* cen and rad. */
  471. X
  472. X
  473. Xfind_bounding_sphere()
  474. X{
  475. Xregister int i;
  476. Xregister double dx,dy,dz;
  477. Xregister double rad_sq,xspan,yspan,zspan,maxspan;
  478. Xdouble old_to_p,old_to_p_sq,old_to_new;
  479. Xstruct Point3Struct xmin,xmax,ymin,ymax,zmin,zmax,dia1,dia2;
  480. X
  481. X
  482. X/* FIRST PASS: find 6 minima/maxima points */
  483. Xxmin.x=ymin.y=zmin.z= BIGNUMBER; /* initialize for min/max compare */
  484. Xxmax.x=ymax.y=zmax.z= -BIGNUMBER;
  485. Xfor (i=0;i<NUM_POINTS;i++)
  486. X    {
  487. X    GET_iTH_POINT(i); /* load global struct caller_p with */
  488. X                    /* his ith point. */
  489. X    if (caller_p.x<xmin.x)
  490. X        xmin = caller_p; /* New xminimum point */
  491. X    if (caller_p.x>xmax.x)
  492. X        xmax = caller_p;
  493. X    if (caller_p.y<ymin.y)
  494. X        ymin = caller_p;
  495. X    if (caller_p.y>ymax.y)
  496. X        ymax = caller_p;
  497. X    if (caller_p.z<zmin.z)
  498. X        zmin = caller_p;
  499. X    if (caller_p.z>zmax.z)
  500. X        zmax = caller_p;
  501. X    }
  502. X/* Set xspan = distance between the 2 points xmin & xmax (squared) */
  503. Xdx = xmax.x - xmin.x;
  504. Xdy = xmax.y - xmin.y;
  505. Xdz = xmax.z - xmin.z;
  506. Xxspan = dx*dx + dy*dy + dz*dz;
  507. X
  508. X/* Same for y & z spans */
  509. Xdx = ymax.x - ymin.x;
  510. Xdy = ymax.y - ymin.y;
  511. Xdz = ymax.z - ymin.z;
  512. Xyspan = dx*dx + dy*dy + dz*dz;
  513. X
  514. Xdx = zmax.x - zmin.x;
  515. Xdy = zmax.y - zmin.y;
  516. Xdz = zmax.z - zmin.z;
  517. Xzspan = dx*dx + dy*dy + dz*dz;
  518. X
  519. X/* Set points dia1 & dia2 to the maximally seperated pair */
  520. Xdia1 = xmin; dia2 = xmax; /* assume xspan biggest */
  521. Xmaxspan = xspan;
  522. Xif (yspan>maxspan)
  523. X    {
  524. X    maxspan = yspan;
  525. X    dia1 = ymin; dia2 = ymax;
  526. X    }
  527. Xif (zspan>maxspan)
  528. X    {
  529. X    dia1 = zmin; dia2 = zmax;
  530. X    }
  531. X
  532. X
  533. X/* dia1,dia2 is a diameter of initial sphere */
  534. X/* calc initial center */
  535. Xcen.x = (dia1.x+dia2.x)/2.0;
  536. Xcen.y = (dia1.y+dia2.y)/2.0;
  537. Xcen.z = (dia1.z+dia2.z)/2.0;
  538. X/* calculate initial radius**2 and radius */
  539. Xdx = dia2.x-cen.x; /* x componant of radius vector */
  540. Xdy = dia2.y-cen.y; /* y componant of radius vector */
  541. Xdz = dia2.z-cen.z; /* z componant of radius vector */
  542. Xrad_sq = dx*dx + dy*dy + dz*dz;
  543. Xrad = sqrt(rad_sq);
  544. X
  545. X/* SECOND PASS: increment current sphere */
  546. X
  547. Xfor (i=0;i<NUM_POINTS;i++)
  548. X    {
  549. X    GET_iTH_POINT(i); /* load global struct caller_p  */
  550. X                    /* with his ith point. */
  551. X    dx = caller_p.x-cen.x;
  552. X    dy = caller_p.y-cen.y;
  553. X    dz = caller_p.z-cen.z;
  554. X    old_to_p_sq = dx*dx + dy*dy + dz*dz;
  555. X    if (old_to_p_sq > rad_sq)     /* do r**2 test first */
  556. X        {     /* this point is outside of current sphere */
  557. X        old_to_p = sqrt(old_to_p_sq);
  558. X        /* calc radius of new sphere */
  559. X        rad = (rad + old_to_p) / 2.0;
  560. X        rad_sq = rad*rad;     /* for next r**2 compare */
  561. X        old_to_new = old_to_p - rad;
  562. X        /* calc center of new sphere */
  563. X        cen.x = (rad*cen.x + old_to_new*caller_p.x) / old_to_p;
  564. X        cen.y = (rad*cen.y + old_to_new*caller_p.y) / old_to_p;
  565. X        cen.z = (rad*cen.z + old_to_new*caller_p.z) / old_to_p;
  566. X        /* Suppress if desired */
  567. X        printf("\n New sphere: cen,rad = %f %f %f   %f",
  568. X            cen.x,cen.y,cen.z, rad);
  569. X        }    
  570. X    }
  571. X}              /* end of find_bounding_sphere()  */
  572. END_OF_FILE
  573. if test 3767 -ne `wc -c <'BoundSphere.c'`; then
  574.     echo shar: \"'BoundSphere.c'\" unpacked with wrong size!
  575. fi
  576. # end of 'BoundSphere.c'
  577. fi
  578. if test -f 'Dissolve.c' -a "${1}" != "-c" ; then 
  579.   echo shar: Will not clobber existing file \"'Dissolve.c'\"
  580. else
  581. echo shar: Extracting \"'Dissolve.c'\" \(4596 characters\)
  582. sed "s/^X//" >'Dissolve.c' <<'END_OF_FILE'
  583. X/* A Digital Dissolve Effect
  584. Xby Mike Morton
  585. Xfrom "Graphics Gems", Academic Press, 1990
  586. X*/
  587. X
  588. X/*
  589. X * Code fragment to advance from one element to the next.
  590. X *
  591. X * int reg;                /* current sequence element
  592. X * reg = 1;                /* start in any non-zero state
  593. X * if (reg & 1)                /* is the bottom bit set?
  594. X *     reg = (reg >>1) ^ MASK;        /* yes: toss out 1 bit; XOR in mask
  595. X * else reg = reg >>1;            /* no: toss out 0 bit 
  596. X */
  597. X
  598. Xint randmasks[32];    /* Gotta fill this in yourself. */
  599. X
  600. Xdissolve1 (height, width)    /* first version of the dissolve                                 /* algorithm */
  601. X    int height, width;    /* number of rows, columns */
  602. X{
  603. X    int pixels, lastnum;    /* number of pixels; */
  604. X                /* last pixel's number */
  605. X    int regwidth;        /* "width" of sequence generator */
  606. X    register long mask;    /* mask to XOR with to*/
  607. X                    /* create sequence */
  608. X    register unsigned long element; 
  609. X                    /* one element of random sequence */
  610. X    register int row, column;
  611. X                    /* row and column numbers for a pixel */
  612. X
  613. X      /* Find smallest register which produces enough pixel numbers */
  614. X     pixels = height * width; /* compute number of pixels */
  615. X                            /* to dissolve */
  616. X     lastnum = pixels-1;    /* find last element (they go 0..lastnum) */
  617. X     regwidth = bitwidth (lastnum); /* how wide must the */
  618. X                    /* register be? */
  619. X     mask = randmasks [regwidth];    /* which mask is for that width? */
  620. X
  621. X     /* Now cycle through all sequence elements. */
  622. X
  623. X      element = 1;    /* 1st element (could be any nonzero) */
  624. X
  625. X
  626. X      do {
  627. X        row = element / width;    /* how many rows down is this pixel? */
  628. X        column = element % width;    /* and how many columns across? */
  629. X        if (row < height)    /* is this seq element in the array? */
  630. X          copy (row, column);    /* yes: copy the (r,c)'th pixel */
  631. X
  632. X        /* Compute the next sequence element */
  633. X        if (element & 1)        /* is the low bit set? */
  634. X          element = (element >>1)^mask;    /* yes: shift value, */
  635. X                        /* XOR in mask */
  636. X        else element = (element >>1);    /* no: just shift the value */
  637. X     } while (element != 1);        /* loop until we return  */
  638. X                        /* to original element */
  639. X     copy (0, 0);        /* kludge: the loop doesn't produce (0,0) */
  640. X}                        /* end of dissolve1() */
  641. X
  642. X
  643. X
  644. Xint bitwidth (N)    /* find "bit-width" needed to represent N */
  645. X    unsigned int N;    /* number to compute the width of */
  646. X{
  647. X     int width = 0;    /* initially, no bits needed to represent N */
  648. X     while (N != 0) {    /* loop 'til N has been whittled down to 0 */
  649. X        N >>= 1;        /* shift N right 1 bit (NB: N is unsigned) */
  650. X        width++;        /* and remember how wide N is */
  651. X      }            /* end of loop shrinking N down to nothing *
  652. X      return (width);    /* return bit positions counted */
  653. X
  654. X}                        /* end of bitwidth() */
  655. X
  656. X
  657. X
  658. Xdissolve2 (height, width)    /* fast version of the dissolve algorithm */
  659. X    int height, width;    /* number of rows, columns */
  660. X{
  661. X    int rwidth, cwidth;    /* bit width for rows, for columns */
  662. X    int regwidth;        /* "width" of sequence generator */
  663. X    register long mask;    /* mask to XOR with to create sequence */
  664. X    register int rowshift;    /* shift distance to get row  */
  665. X                            /* from element */
  666. X    register int colmask; /* mask to extract column from element */
  667. X    register unsigned long element; /* one element of random */                                     /* sequence */
  668. X    register int row, column;    /* row and column for one pixel */
  669. X
  670. X
  671. X      /* Find the mask to produce all rows and columns. */
  672. X
  673. X    rwidth = bitwidth (height); /* how many bits needed for height? */
  674. X    cwidth = bitwidth (width);  /* how many bits needed for width? */
  675. X    regwidth = rwidth + cwidth; /* how wide must the register be? */
  676. X    mask = randmasks [regwidth]; /* which mask is for that width? */
  677. X
  678. X /* Find values to extract row and col numbers from each element. */
  679. X    rowshift = cwidth; /* find dist to shift to get top bits (row) */
  680. X    colmask = (1<<cwidth)-1;    /* find mask to extract  */
  681. X                        /* bottom bits (col) */
  682. X
  683. X      /* Now cycle through all sequence elements. */
  684. X
  685. X    element = 1;    /* 1st element (could be any nonzero) */
  686. X    do {
  687. X        row = element >> rowshift; /* find row number for this pixel */
  688. X        column = element & colmask; /* and how many columns across? */
  689. X        if ((row < height)    /* does element fall in the array? */
  690. X            && (column < width)) /* ...must check row AND column */
  691. X        copy (row, column); /* in bounds: copy the (r,c)'th pixel */
  692. X
  693. X        /* Compute the next sequence element */
  694. X        if (element & 1)        /* is the low bit set? */
  695. X        element = (element >>1)^mask; /* yes: shift value, /*
  696. X                        /* XOR in mask */
  697. X        else element = (element >>1); /* no: just shift the value */
  698. X    } while (element != 1);     /* loop until we return to */
  699. X                    /*  original element */
  700. X
  701. X    copy (0, 0);        /* kludge: element never comes up zero */
  702. X}                    /* end of dissolve2() */
  703. END_OF_FILE
  704. if test 4596 -ne `wc -c <'Dissolve.c'`; then
  705.     echo shar: \"'Dissolve.c'\" unpacked with wrong size!
  706. fi
  707. # end of 'Dissolve.c'
  708. fi
  709. if test -f 'DoubleLine.c' -a "${1}" != "-c" ; then 
  710.   echo shar: Will not clobber existing file \"'DoubleLine.c'\"
  711. else
  712. echo shar: Extracting \"'DoubleLine.c'\" \(4647 characters\)
  713. sed "s/^X//" >'DoubleLine.c' <<'END_OF_FILE'
  714. X/*
  715. XSymmetric Double Step Line Algorithm
  716. Xby Brian Wyvill
  717. Xfrom "Graphics Gems", Academic Press, 1990
  718. X*/
  719. X
  720. X#define swap(a,b)           {a^=b; b^=a; a^=b;}
  721. X#define absolute(i,j,k)     ( (i-j)*(k = ( (i-j)<0 ? -1 : 1)))
  722. Xint
  723. Xsymwuline(a1, b1, a2, b2) int a1, b1, a2, b2;
  724. X{
  725. X    int           dx, dy, incr1, incr2, D, x, y, xend, c, pixels_left;
  726. X    int           x1, y1;
  727. X    int           sign_x, sign_y, step, reverse, i;
  728. X
  729. X    dx = absolute(a2, a1, sign_x);
  730. X    dy = absolute(b2, b1, sign_y);
  731. X    /* decide increment sign by the slope sign */
  732. X    if (sign_x == sign_y)
  733. X        step = 1;
  734. X    else
  735. X        step = -1;
  736. X
  737. X    if (dy > dx) {        /* chooses axis of greatest movement (make
  738. X                          * dx) */
  739. X        swap(a1, b1);
  740. X        swap(a2, b2);
  741. X        swap(dx, dy);
  742. X        reverse = 1;
  743. X    } else
  744. X        reverse = 0;
  745. X    /* note error check for dx==0 should be included here */
  746. X    if (a1 > a2) {        /* start from the smaller coordinate */
  747. X        x = a2;
  748. X        y = b2;
  749. X        x1 = a1;
  750. X        y1 = b1;
  751. X    } else {
  752. X        x = a1;
  753. X        y = b1;
  754. X        x1 = a2;
  755. X        y1 = b2;
  756. X    }
  757. X
  758. X
  759. X    /* Note dx=n implies 0 - n or (dx+1) pixels to be set */
  760. X    /* Go round loop dx/4 times then plot last 0,1,2 or 3 pixels */
  761. X    /* In fact (dx-1)/4 as 2 pixels are already plottted */
  762. X    xend = (dx - 1) / 4;
  763. X    pixels_left = (dx - 1) % 4;    /* number of pixels left over at the
  764. X                                  * end */
  765. X    plot(x, y, reverse);
  766. X    plot(x1, y1, reverse);    /* plot first two points */
  767. X    incr2 = 4 * dy - 2 * dx;
  768. X    if (incr2 < 0) {    /* slope less than 1/2 */
  769. X        c = 2 * dy;
  770. X        incr1 = 2 * c;
  771. X        D = incr1 - dx;
  772. X
  773. X        for (i = 0; i < xend; i++) {    /* plotting loop */
  774. X            ++x;
  775. X            --x1;
  776. X            if (D < 0) {
  777. X                              /* pattern 1 forwards */
  778. X                plot(x, y, reverse);
  779. X                plot(++x, y, reverse);
  780. X                                /* pattern 1 backwards */
  781. X                plot(x1, y1, reverse);
  782. X                plot(--x1, y1, reverse);
  783. X                D += incr1;
  784. X            } else {
  785. X                if (D < c) {
  786. X                    /* pattern 2 forwards */
  787. X                    plot(x, y, reverse);
  788. X                    plot(++x, y += step, reverse);
  789. X                    /* pattern 2 backwards */
  790. X                    plot(x1, y1, reverse);
  791. X                    plot(--x1, y1 -= step, reverse);    
  792. X                } else {
  793. X                        /* pattern 3 forwards */
  794. X                    plot(x, y += step, reverse);
  795. X                    plot(++x, y, reverse);
  796. X                    /* pattern 3 backwards */
  797. X                    plot(x1, y1 -= step, reverse);
  798. X                    plot(--x1, y1, reverse);
  799. X                }
  800. X                D + = incr2;
  801. X            }
  802. X        }        /* end for */
  803. X
  804. X        /* plot last pattern */
  805. X        if (pixels_left) {
  806. X            if (D < 0) {
  807. X                plot(++x, y, reverse);    /* pattern 1 */
  808. X                if (pixels_left > 1)
  809. X                    plot(++x, y, reverse);
  810. X                if (pixels_left > 2)
  811. X                    plot(--x1, y1, reverse);
  812. X            } else {
  813. X                if (D < c) {
  814. X                    plot(++x, y, reverse);    /* pattern 2  */
  815. X                    if (pixels_left > 1)
  816. X                        plot(++x, y += step, reverse);
  817. X                    if (pixels_left > 2)
  818. X                        plot(--x1, y1, reverse);
  819. X                } else {
  820. X                  /* pattern 3 */
  821. X                    plot(++x, y += step, reverse);
  822. X                    if (pixels_left > 1)
  823. X                        plot(++x, y, reverse);
  824. X                    if (pixels_left > 2)
  825. X                        plot(--x1, y1 -= step, reverse);
  826. X                }
  827. X            }
  828. X        }        /* end if pixels_left */
  829. X    }
  830. X    /* end slope < 1/2 */
  831. X    else {            /* slope greater than 1/2 */
  832. X        c = 2 * (dy - dx);
  833. X        incr1 = 2 * c;
  834. X        D = incr1 + dx;
  835. X        for (i = 0; i < xend; i++) {
  836. X            ++x;
  837. X            --x1;
  838. X            if (D > 0) {
  839. X              /* pattern 4 forwards */
  840. X                plot(x, y += step, reverse);
  841. X                plot(++x, y += step, reverse);
  842. X              /* pattern 4 backwards */
  843. X                plot(x1, y1 -= step, reverse);
  844. X                plot(--x1, y1 -= step, reverse);
  845. X                D += incr1;
  846. X            } else {
  847. X                if (D < c) {
  848. X                  /* pattern 2 forwards */
  849. X                    plot(x, y, reverse);
  850. X                    plot(++x, y += step, reverse);
  851. X
  852. X                   /* pattern 2 backwards */
  853. X                    plot(x1, y1, reverse);
  854. X                    plot(--x1, y1 -= step, reverse);
  855. X                } else {
  856. X                  /* pattern 3 forwards */
  857. X                    plot(x, y += step, reverse);
  858. X                    plot(++x, y, reverse);
  859. X                  /* pattern 3 backwards */
  860. X                    plot(x1, y1 -= step, reverse);
  861. X                    plot(--x1, y1, reverse);
  862. X                }
  863. X                D += incr2;
  864. X            }
  865. X        }        /* end for */
  866. X        /* plot last pattern */
  867. X        if (pixels_left) {
  868. X            if (D > 0) {
  869. X                plot(++x, y += step, reverse);    /* pattern 4 */
  870. X                if (pixels_left > 1)
  871. X                    plot(++x, y += step, reverse);
  872. X                if (pixels_left > 2)
  873. X                    plot(--x1, y1 -= step, reverse);
  874. X            } else {
  875. X                if (D < c) {
  876. X                    plot(++x, y, reverse);    /* pattern 2  */
  877. X                    if (pixels_left > 1)
  878. X                        plot(++x, y += step, reverse);
  879. X                    if (pixels_left > 2)
  880. X                        plot(--x1, y1, reverse);
  881. X                } else {
  882. X                  /* pattern 3 */
  883. X                    plot(++x, y += step, reverse);
  884. X                    if (pixels_left > 1)
  885. X                        plot(++x, y, reverse);
  886. X                    if (pixels_left > 2) {
  887. X                        if (D > c) /* step 3 */
  888. X                           plot(--x1, y1 -= step, reverse);
  889. X                        else /* step 2 */
  890. X                            plot(--x1, y1, reverse);
  891. X                                 }
  892. X                }
  893. X            }
  894. X        }
  895. X    }
  896. X}
  897. X/* non-zero flag indicates the pixels needing swap back. */
  898. Xplot(x, y, flag) int x, y, flag;
  899. X{
  900. X    if (flag)
  901. X        setpixel(y, x);
  902. X    else
  903. X        setpixel(x, y);
  904. X}
  905. X
  906. END_OF_FILE
  907. if test 4647 -ne `wc -c <'DoubleLine.c'`; then
  908.     echo shar: \"'DoubleLine.c'\" unpacked with wrong size!
  909. fi
  910. # end of 'DoubleLine.c'
  911. fi
  912. if test -f 'GraphicsGems.h' -a "${1}" != "-c" ; then 
  913.   echo shar: Will not clobber existing file \"'GraphicsGems.h'\"
  914. else
  915. echo shar: Extracting \"'GraphicsGems.h'\" \(4049 characters\)
  916. sed "s/^X//" >'GraphicsGems.h' <<'END_OF_FILE'
  917. X/* 
  918. X * GraphicsGems.h  
  919. X * Version 1.0 - Andrew Glassner
  920. X * from "Graphics Gems", Academic Press, 1990
  921. X */
  922. X
  923. X#ifndef GG_H
  924. X
  925. X#define GG_H 1
  926. X
  927. X/*********************/
  928. X/* 2d geometry types */
  929. X/*********************/
  930. X
  931. Xtypedef struct Point2Struct {    /* 2d point */
  932. X    double x, y;
  933. X    } Point2;
  934. Xtypedef Point2 Vector2;
  935. X
  936. Xtypedef struct IntPoint2Struct {    /* 2d integer point */
  937. X    int x, y;
  938. X    } IntPoint2;
  939. X
  940. Xtypedef struct Matrix3Struct {    /* 3-by-3 matrix */
  941. X    double element[3][3];
  942. X    } Matrix3;
  943. X
  944. Xtypedef struct Box2dStruct {        /* 2d box */
  945. X    Point2 min, max;
  946. X    } Box2;
  947. X    
  948. X
  949. X/*********************/
  950. X/* 3d geometry types */
  951. X/*********************/
  952. X
  953. Xtypedef struct Point3Struct {    /* 3d point */
  954. X    double x, y, z;
  955. X    } Point3;
  956. Xtypedef Point3 Vector3;
  957. X
  958. Xtypedef struct IntPoint3Struct {    /* 3d integer point */
  959. X    int x, y, z;
  960. X    } IntPoint3;
  961. X
  962. X
  963. Xtypedef struct Matrix4Struct {    /* 4-by-4 matrix */
  964. X    double element[4][4];
  965. X    } Matrix4;
  966. X
  967. Xtypedef struct Box3dStruct {        /* 3d box */
  968. X    Point3 min, max;
  969. X    } Box3;
  970. X
  971. X
  972. X
  973. X/***********************/
  974. X/* one-argument macros */
  975. X/***********************/
  976. X
  977. X/* absolute value of a */
  978. X#define ABS(a)        (((a)<0) ? -(a) : (a))
  979. X
  980. X/* round a to nearest integer towards 0 */
  981. X#define FLOOR(a)        ((a)>0 ? (int)(a) : -(int)(-a))
  982. X
  983. X/* round a to nearest integer away from 0 */
  984. X#define CEILING(a) \
  985. X((a)==(int)(a) ? (a) : (a)>0 ? 1+(int)(a) : -(1+(int)(-a)))
  986. X
  987. X/* round a to nearest int */
  988. X#define ROUND(a)    ((a)>0 ? (int)(a+0.5) : -(int)(0.5-a))        
  989. X
  990. X/* take sign of a, either -1, 0, or 1 */
  991. X#define ZSGN(a)        (((a)<0) ? -1 : (a)>0 ? 1 : 0)    
  992. X
  993. X/* take binary sign of a, either -1, or 1 if >= 0 */
  994. X#define SGN(a)        (((a)<0) ? -1 : 0)
  995. X
  996. X/* shout if something that should be true isn't */
  997. X#define ASSERT(x) \
  998. Xif (!(x)) fprintf(stderr," Assert failed: x\n");
  999. X
  1000. X/* square a */
  1001. X#define SQR(a)        ((a)*(a))    
  1002. X
  1003. X
  1004. X/***********************/
  1005. X/* two-argument macros */
  1006. X/***********************/
  1007. X
  1008. X/* find minimum of a and b */
  1009. X#define MIN(a,b)    (((a)<(b))?(a):(b))    
  1010. X
  1011. X/* find maximum of a and b */
  1012. X#define MAX(a,b)    (((a)>(b))?(a):(b))    
  1013. X
  1014. X/* swap a and b (see Gem by Wyvill) */
  1015. X#define SWAP(a,b)    { a^=b; b^=a; a^=b; }
  1016. X
  1017. X/* linear interpolation from l (when a=0) to h (when a=1)*/
  1018. X/* (equal to (a*h)+((1-a)*l) */
  1019. X#define LERP(a,l,h)    ((l)+(((h)-(l))*(a)))
  1020. X
  1021. X/* clamp the input to the specified range */
  1022. X#define CLAMP(v,l,h)    ((v)<(l) ? (l) : (v) > (h) ? (h) : v)
  1023. X
  1024. X
  1025. X/****************************/
  1026. X/* memory allocation macros */
  1027. X/****************************/
  1028. X
  1029. X/* create a new instance of a structure (see Gem by Hultquist) */
  1030. X#define NEWSTRUCT(x)    (struct x *)(malloc((unsigned)sizeof(struct x)))
  1031. X
  1032. X/* create a new instance of a type */
  1033. X#define NEWTYPE(x)    (x *)(malloc((unsigned)sizeof(x)))
  1034. X
  1035. X
  1036. X/********************/
  1037. X/* useful constants */
  1038. X/********************/
  1039. X
  1040. X#define PI        3.141592    /* the venerable pi */
  1041. X#define PITIMES2    6.283185    /* 2 * pi */
  1042. X#define PIOVER2        1.570796    /* pi / 2 */
  1043. X#define E        2.718282    /* the venerable e */
  1044. X#define SQRT2        1.414214    /* sqrt(2) */
  1045. X#define SQRT3        1.732051    /* sqrt(3) */
  1046. X#define GOLDEN        1.618034    /* the golden ratio */
  1047. X#define DTOR        0.017453    /* convert degrees to radians */
  1048. X#define RTOD        57.29578    /* convert radians to degrees */
  1049. X
  1050. X
  1051. X/************/
  1052. X/* booleans */
  1053. X/************/
  1054. X
  1055. X#define TRUE        1
  1056. X#define FALSE        0
  1057. X#define ON        1
  1058. X#define OFF         0
  1059. Xtypedef int boolean;            /* boolean data type */
  1060. Xtypedef boolean flag;            /* flag data type */
  1061. X
  1062. Xextern double V2SquaredLength(), V2Length();
  1063. Xextern double V2Dot(), V2DistanceBetween2Points(); 
  1064. Xextern Vector2 *V2Negate(), *V2Normalize(), *V2Scale(), *V2Add(), *V2Sub();
  1065. Xextern Vector2 *V2Lerp(), *V2Combine(), *V2Mul(), *V2MakePerpendicular();
  1066. Xextern Vector2 *V2New(), *V2Duplicate();
  1067. Xextern Point2 *V2MulPointByMatrix();
  1068. Xextern Matrix3 *V2MatMul();
  1069. X
  1070. Xextern double V3SquaredLength(), V3Length();
  1071. Xextern double V3Dot(), V3DistanceBetween2Points();
  1072. Xextern Vector3 *V3Normalize(), *V3Scale(), *V3Add(), *V3Sub();
  1073. Xextern Vector3 *V3Lerp(), *V3Combine(), *V3Mul(), *V3Cross();
  1074. Xextern Vector3 *V3New(), *V3Duplicate();
  1075. Xextern Point3 *V3MulPointByMatrix();
  1076. Xextern Matrix4 *V3MatMul();
  1077. X
  1078. Xextern double RegulaFalsi(), NewtonRaphson(), findroot();
  1079. X
  1080. X#endif
  1081. END_OF_FILE
  1082. if test 4049 -ne `wc -c <'GraphicsGems.h'`; then
  1083.     echo shar: \"'GraphicsGems.h'\" unpacked with wrong size!
  1084. fi
  1085. # end of 'GraphicsGems.h'
  1086. fi
  1087. if test -f 'LineEdge.c' -a "${1}" != "-c" ; then 
  1088.   echo shar: Will not clobber existing file \"'LineEdge.c'\"
  1089. else
  1090. echo shar: Extracting \"'LineEdge.c'\" \(3852 characters\)
  1091. sed "s/^X//" >'LineEdge.c' <<'END_OF_FILE'
  1092. X/* 
  1093. XFast Line-Edge Intersections on a Uniform Grid 
  1094. Xby Andrew Shapira
  1095. Xfrom "Graphics Gems", Academic Press, 1990
  1096. X*/
  1097. X
  1098. X#include "GraphicsGems.h"
  1099. X
  1100. X#define OCTANT(f1, f2, f3, f4, f5, i1, s1, r1, r2) \
  1101. X    for (f1, f2, f3, nr = 0; f4; f5) { \
  1102. X        if (nr < liconst) { \
  1103. X            if (i1) \
  1104. X                r1(&C); \
  1105. X            else \
  1106. X                vertex(&C); \
  1107. X        } \
  1108. X        else { \
  1109. X            s1; \
  1110. X            if (nr -= liconst) { \
  1111. X                r2(&C); \
  1112. X                r1(&C); \
  1113. X            } \
  1114. X            else \
  1115. X                vertex(&C); \
  1116. X        } \
  1117. X    }
  1118. X
  1119. Xfind_intersections(Pptr, Qptr)
  1120. XIntPoint2   *Pptr, *Qptr;       /* P and Q as described in gem text */
  1121. X{
  1122. X    IntPoint2   P, Q;           /* P and Q, dereferenced for speed */
  1123. X    IntPoint2   C;              /* current grid point */
  1124. X    int         nr;             /* remainder */
  1125. X    int         deltax, deltay; /* Q.x - P.x, Q.y - P.y */
  1126. X    int         liconst;          /* loop-invariant constant */
  1127. X
  1128. X    P.x = Pptr->x;
  1129. X    P.y = Pptr->y;
  1130. X    Q.x = Qptr->x;
  1131. X    Q.y = Qptr->y;
  1132. X    deltax = Q.x - P.x;
  1133. X    deltay = Q.y - P.y;
  1134. X
  1135. X
  1136. X    /* for reference purposes, let theta be the angle from P to Q */
  1137. X
  1138. X    if ((deltax >= 0) && (deltay >= 0) && (deltay < deltax)) 
  1139. X                        /* 0 <= theta < 45 */
  1140. X        OCTANT(C.x = P.x + 1, C.y = P.y, liconst = deltax - deltay, 
  1141. X            C.x < Q.x, C.x++, nr += deltay, C.y++, up, left)
  1142. X    else if ((deltax > 0) && (deltay >= 0) && (deltay >= deltax)) 
  1143. X                       /* 45 <= theta < 90 */
  1144. X        OCTANT(C.y = P.y + 1, C.x = P.x, liconst = deltay - deltax,
  1145. X             C.y < Q.y, C.y++, nr += deltax, C.x++, right, down)
  1146. X    else if ((deltax <= 0) && (deltay >= 0) && (deltay > -deltax))
  1147. X                       /* 90 <= theta < 135 */
  1148. X        OCTANT(C.y = P.y + 1, C.x = P.x, liconst = deltay + deltax,
  1149. X             C.y < Q.y, C.y++, nr -= deltax, C.x--, left, down)
  1150. X    else if ((deltax <= 0) && (deltay > 0) && (deltay <= -deltax)) 
  1151. X                       /* 135 <= theta < 180 */
  1152. X        OCTANT(C.x = P.x - 1, C.y = P.y, liconst = -deltax - deltay,
  1153. X             C.x > Q.x, C.x--, nr += deltay, C.y++, up, right)
  1154. X    else if ((deltax <= 0) && (deltay <= 0) && (deltay > deltax))
  1155. X                      /* 180 <= theta < 225 */
  1156. X        OCTANT(C.x = P.x - 1, C.y = P.y, liconst = -deltax + deltay, 
  1157. X            C.x > Q.x, C.x--, nr -= deltay, C.y--, down, right)
  1158. X    else if ((deltax < 0) && (deltay <= 0) && (deltay <= deltax))
  1159. X                      /* 225 <= theta < 270 */
  1160. X        OCTANT(C.y = P.y - 1, C.x = P.x, liconst = -deltay + deltax,
  1161. X            C.y > Q.y, C.y--, nr -= deltax, C.x--, left, up)
  1162. X    else if ((deltax >= 0) && (deltay <= 0) && (-deltay > deltax))
  1163. X                     /* 270 <= theta < 315 */
  1164. X        OCTANT(C.y = P.y - 1, C.x = P.x, liconst = -deltay - deltax, 
  1165. X            C.y > Q.y, C.y--, nr += deltax, C.x++, right, up)
  1166. X    else if ((deltax >= 0) && (deltay < 0) && (-deltay <= deltax))
  1167. X                     /* 315 <= theta < 360 */
  1168. X        OCTANT(C.x = P.x + 1, C.y = P.y, liconst = deltax + deltay,
  1169. X             C.x < Q.x, C.x++, nr -= deltay, C.y--, down, left)
  1170. X    else {}                    /* P = Q */
  1171. X}
  1172. X
  1173. Xvertex(I)
  1174. XIntPoint2   *I;
  1175. X{
  1176. X    /* Note: replace printf with code to process vertex, if desired */
  1177. X    (void) printf("vertex at %d %d\n", I->x, I->y);
  1178. X}
  1179. X
  1180. Xleft(I)
  1181. XIntPoint2   *I;
  1182. X{
  1183. X
  1184. X    /* Note: replace printf with code to process leftward */     
  1185. X    /* intersection, if desired */
  1186. X    (void) printf("left from %d %d\n", I->x, I->y);
  1187. X}
  1188. X
  1189. Xup(I)
  1190. XIntPoint2   *I;
  1191. X{
  1192. X    /* Note: replace printf with code to process upward */
  1193. X    /* intersection, if desired */
  1194. X    (void) printf("up from %d %d\n", I->x, I->y);
  1195. X}
  1196. X
  1197. Xright(I)
  1198. XIntPoint2   *I;
  1199. X{
  1200. X    /* Note: replace printf with code to process rightward */
  1201. X    /* intersection, if desired */
  1202. X    (void) printf("right from %d %d\n", I->x, I->y);
  1203. X}
  1204. X
  1205. Xdown(I)
  1206. XIntPoint2   *I;
  1207. X{
  1208. X    /* Note: replace printf with code to process downward */
  1209. X    /* intersection, if desired */
  1210. X    (void) printf("down from %d %d\n", I->x, I->y);
  1211. X}
  1212. END_OF_FILE
  1213. if test 3852 -ne `wc -c <'LineEdge.c'`; then
  1214.     echo shar: \"'LineEdge.c'\" unpacked with wrong size!
  1215. fi
  1216. # end of 'LineEdge.c'
  1217. fi
  1218. if test -f 'MatrixInvert.c' -a "${1}" != "-c" ; then 
  1219.   echo shar: Will not clobber existing file \"'MatrixInvert.c'\"
  1220. else
  1221. echo shar: Extracting \"'MatrixInvert.c'\" \(4893 characters\)
  1222. sed "s/^X//" >'MatrixInvert.c' <<'END_OF_FILE'
  1223. X/*
  1224. XMatrix Inversion
  1225. Xby Richard Carling
  1226. Xfrom "Graphics Gems", Academic Press, 1990
  1227. X*/
  1228. X
  1229. X#define SMALL_NUMBER    1.e-8
  1230. X/* 
  1231. X *   inverse( original_matrix, inverse_matrix )
  1232. X * 
  1233. X *    calculate the inverse of a 4x4 matrix
  1234. X *
  1235. X *     -1     
  1236. X *     A  = ___1__ adjoint A
  1237. X *         det A
  1238. X */
  1239. X
  1240. X#include "GraphicsGems.h"
  1241. Xinverse( in, out ) Matrix4 *in, *out;
  1242. X{
  1243. X    int i, j;
  1244. X    double det, det4x4();
  1245. X
  1246. X    /* calculate the adjoint matrix */
  1247. X
  1248. X    adjoint( in, out );
  1249. X
  1250. X    /*  calculate the 4x4 determinent
  1251. X     *  if the determinent is zero, 
  1252. X     *  then the inverse matrix is not unique.
  1253. X     */
  1254. X
  1255. X    det = det4x4( in );
  1256. X
  1257. X    if ( fabs( det ) < SMALL_NUMBER) {
  1258. X        printf("Non-singular matrix, no inverse!\n");
  1259. X        exit();
  1260. X    }
  1261. X
  1262. X    /* scale the adjoint matrix to get the inverse */
  1263. X
  1264. X    for (i=0; i<4; i++)
  1265. X        for(j=0; j<4; j++)
  1266. X        out->element[i][j] = out->element[i][j] / det;
  1267. X}
  1268. X
  1269. X
  1270. X/* 
  1271. X *   adjoint( original_matrix, inverse_matrix )
  1272. X * 
  1273. X *     calculate the adjoint of a 4x4 matrix
  1274. X *
  1275. X *      Let  a   denote the minor determinant of matrix A obtained by
  1276. X *           ij
  1277. X *
  1278. X *      deleting the ith row and jth column from A.
  1279. X *
  1280. X *                    i+j
  1281. X *     Let  b   = (-1)    a
  1282. X *          ij            ji
  1283. X *
  1284. X *    The matrix B = (b  ) is the adjoint of A
  1285. X *                     ij
  1286. X */
  1287. X
  1288. Xadjoint( in, out ) Matrix4 *in; Matrix4 *out;
  1289. X{
  1290. X    double a1, a2, a3, a4, b1, b2, b3, b4;
  1291. X    double c1, c2, c3, c4, d1, d2, d3, d4;
  1292. X    double det3x3();
  1293. X
  1294. X    /* assign to individual variable names to aid  */
  1295. X    /* selecting correct values  */
  1296. X
  1297. X    a1 = in->element[0][0]; b1 = in->element[0][1]; 
  1298. X    c1 = in->element[0][2]; d1 = in->element[0][3];
  1299. X
  1300. X    a2 = in->element[1][0]; b2 = in->element[1][1]; 
  1301. X    c2 = in->element[1][2]; d2 = in->element[1][3];
  1302. X
  1303. X    a3 = in->element[2][0]; b3 = in->element[2][1];
  1304. X    c3 = in->element[2][2]; d3 = in->element[2][3];
  1305. X
  1306. X    a4 = in->element[3][0]; b4 = in->element[3][1]; 
  1307. X    c4 = in->element[3][2]; d4 = in->element[3][3];
  1308. X
  1309. X
  1310. X    /* row column labeling reversed since we transpose rows & columns */
  1311. X
  1312. X    out->element[0][0]  =   det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4);
  1313. X    out->element[1][0]  = - det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4);
  1314. X    out->element[2][0]  =   det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4);
  1315. X    out->element[3][0]  = - det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4);
  1316. X        
  1317. X    out->element[0][1]  = - det3x3( b1, b3, b4, c1, c3, c4, d1, d3, d4);
  1318. X    out->element[1][1]  =   det3x3( a1, a3, a4, c1, c3, c4, d1, d3, d4);
  1319. X    out->element[2][1]  = - det3x3( a1, a3, a4, b1, b3, b4, d1, d3, d4);
  1320. X    out->element[3][1]  =   det3x3( a1, a3, a4, b1, b3, b4, c1, c3, c4);
  1321. X        
  1322. X    out->element[0][2]  =   det3x3( b1, b2, b4, c1, c2, c4, d1, d2, d4);
  1323. X    out->element[1][2]  = - det3x3( a1, a2, a4, c1, c2, c4, d1, d2, d4);
  1324. X    out->element[2][2]  =   det3x3( a1, a2, a4, b1, b2, b4, d1, d2, d4);
  1325. X    out->element[3][2]  = - det3x3( a1, a2, a4, b1, b2, b4, c1, c2, c4);
  1326. X        
  1327. X    out->element[0][3]  = - det3x3( b1, b2, b3, c1, c2, c3, d1, d2, d3);
  1328. X    out->element[1][3]  =   det3x3( a1, a2, a3, c1, c2, c3, d1, d2, d3);
  1329. X    out->element[2][3]  = - det3x3( a1, a2, a3, b1, b2, b3, d1, d2, d3);
  1330. X    out->element[3][3]  =   det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3);
  1331. X}
  1332. X/*
  1333. X * double = det4x4( matrix )
  1334. X * 
  1335. X * calculate the determinent of a 4x4 matrix.
  1336. X */
  1337. Xdouble det4x4( m ) Matrix4 *m;
  1338. X{
  1339. X    double ans;
  1340. X    double a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3,             d4;
  1341. X    double det3x3();
  1342. X
  1343. X    /* assign to individual variable names to aid selecting */
  1344. X    /*  correct elements */
  1345. X
  1346. X    a1 = m->element[0][0]; b1 = m->element[0][1]; 
  1347. X    c1 = m->element[0][2]; d1 = m->element[0][3];
  1348. X
  1349. X    a2 = m->element[1][0]; b2 = m->element[1][1]; 
  1350. X    c2 = m->element[1][2]; d2 = m->element[1][3];
  1351. X
  1352. X    a3 = m->element[2][0]; b3 = m->element[2][1]; 
  1353. X    c3 = m->element[2][2]; d3 = m->element[2][3];
  1354. X
  1355. X    a4 = m->element[3][0]; b4 = m->element[3][1]; 
  1356. X    c4 = m->element[3][2]; d4 = m->element[3][3];
  1357. X
  1358. X    ans = a1 * det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4)
  1359. X        - b1 * det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4)
  1360. X        + c1 * det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4)
  1361. X        - d1 * det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4);
  1362. X    return ans;
  1363. X}
  1364. X
  1365. X
  1366. X
  1367. X/*
  1368. X * double = det3x3(  a1, a2, a3, b1, b2, b3, c1, c2, c3 )
  1369. X * 
  1370. X * calculate the determinent of a 3x3 matrix
  1371. X * in the form
  1372. X *
  1373. X *     | a1,  b1,  c1 |
  1374. X *     | a2,  b2,  c2 |
  1375. X *     | a3,  b3,  c3 |
  1376. X */
  1377. X
  1378. Xdouble det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3 )
  1379. Xdouble a1, a2, a3, b1, b2, b3, c1, c2, c3;
  1380. X{
  1381. X    double ans;
  1382. X    double det2x2();
  1383. X
  1384. X    ans = a1 * det2x2( b2, b3, c2, c3 )
  1385. X        - b1 * det2x2( a2, a3, c2, c3 )
  1386. X        + c1 * det2x2( a2, a3, b2, b3 );
  1387. X    return ans;
  1388. X}
  1389. X
  1390. X/*
  1391. X * double = det2x2( double a, double b, double c, double d )
  1392. X * 
  1393. X * calculate the determinent of a 2x2 matrix.
  1394. X */
  1395. X
  1396. Xdouble det2x2( a, b, c, d)
  1397. Xdouble a, b, c, d; 
  1398. X{
  1399. X    double ans;
  1400. X    ans = a * d - b * c;
  1401. X    return ans;
  1402. X}
  1403. X
  1404. X
  1405. END_OF_FILE
  1406. if test 4893 -ne `wc -c <'MatrixInvert.c'`; then
  1407.     echo shar: \"'MatrixInvert.c'\" unpacked with wrong size!
  1408. fi
  1409. # end of 'MatrixInvert.c'
  1410. fi
  1411. if test -f 'PolyScan/poly_clip.c' -a "${1}" != "-c" ; then 
  1412.   echo shar: Will not clobber existing file \"'PolyScan/poly_clip.c'\"
  1413. else
  1414. echo shar: Extracting \"'PolyScan/poly_clip.c'\" \(4217 characters\)
  1415. sed "s/^X//" >'PolyScan/poly_clip.c' <<'END_OF_FILE'
  1416. X/*
  1417. X * Generic Convex Polygon Scan Conversion and Clipping
  1418. X * by Paul Heckbert
  1419. X * from "Graphics Gems", Academic Press, 1990
  1420. X */
  1421. X
  1422. X/*
  1423. X * poly_clip.c: homogeneous 3-D convex polygon clipper
  1424. X *
  1425. X * Paul Heckbert    1985, Dec 1989
  1426. X */
  1427. X
  1428. X#include "poly.h"
  1429. X
  1430. X#define SWAP(a, b, temp)    {temp = a; a = b; b = temp;}
  1431. X#define COORD(vert, i) ((double *)(vert))[i]
  1432. X
  1433. X#define CLIP_AND_SWAP(elem, sign, k, p, q, r) { \
  1434. X    poly_clip_to_halfspace(p, q, &v->elem-(double *)v, sign, sign*k); \
  1435. X    if (q->n==0) {p1->n = 0; return POLY_CLIP_OUT;} \
  1436. X    SWAP(p, q, r); \
  1437. X}
  1438. X
  1439. X/*
  1440. X * poly_clip_to_box: Clip the convex polygon p1 to the screen space box
  1441. X * using the homogeneous screen coordinates (sx, sy, sz, sw) of each vertex,
  1442. X * testing if v->sx/v->sw > box->x0 and v->sx/v->sw < box->x1,
  1443. X * and similar tests for y and z, for each vertex v of the polygon.
  1444. X * If polygon is entirely inside box, then POLY_CLIP_IN is returned.
  1445. X * If polygon is entirely outside box, then POLY_CLIP_OUT is returned.
  1446. X * Otherwise, if the polygon is cut by the box, p1 is modified and
  1447. X * POLY_CLIP_PARTIAL is returned.
  1448. X */
  1449. X
  1450. Xint poly_clip_to_box(p1, box)
  1451. Xregister Poly *p1;
  1452. Xregister Poly_box *box;
  1453. X{
  1454. X    int x0out = 0, x1out = 0, y0out = 0, y1out = 0, z0out = 0, z1out = 0;
  1455. X    register int i;
  1456. X    register Poly_vert *v;
  1457. X    Poly p2, *p, *q, *r;
  1458. X
  1459. X    /* count vertices "outside" with respect to each of the six planes */
  1460. X    for (v=p1->vert, i=p1->n; i>0; i--, v++) {
  1461. X    if (v->sx < box->x0*v->sw) x0out++;    /* out on left */
  1462. X    if (v->sx > box->x1*v->sw) x1out++;    /* out on right */
  1463. X    if (v->sy < box->y0*v->sw) y0out++;    /* out on top */
  1464. X    if (v->sy > box->y1*v->sw) y1out++;    /* out on bottom */
  1465. X    if (v->sz < box->z0*v->sw) z0out++;    /* out on near */
  1466. X    if (v->sz > box->z1*v->sw) z1out++;    /* out on far */
  1467. X    }
  1468. X
  1469. X    /* check if all vertices inside */
  1470. X    if (x0out+x1out+y0out+y1out+z0out+z1out == 0) return POLY_CLIP_IN;
  1471. X
  1472. X    /* check if all vertices are "outside" any of the six planes */
  1473. X    if (x0out==p1->n || x1out==p1->n || y0out==p1->n ||
  1474. X    y1out==p1->n || z0out==p1->n || z1out==p1->n) {
  1475. X        p1->n = 0;
  1476. X        return POLY_CLIP_OUT;
  1477. X    }
  1478. X
  1479. X    /*
  1480. X     * now clip against each of the planes that might cut the polygon,
  1481. X     * at each step toggling between polygons p1 and p2
  1482. X     */
  1483. X    p = p1;
  1484. X    q = &p2;
  1485. X    if (x0out) CLIP_AND_SWAP(sx, -1., box->x0, p, q, r);
  1486. X    if (x1out) CLIP_AND_SWAP(sx,  1., box->x1, p, q, r);
  1487. X    if (y0out) CLIP_AND_SWAP(sy, -1., box->y0, p, q, r);
  1488. X    if (y1out) CLIP_AND_SWAP(sy,  1., box->y1, p, q, r);
  1489. X    if (z0out) CLIP_AND_SWAP(sz, -1., box->z0, p, q, r);
  1490. X    if (z1out) CLIP_AND_SWAP(sz,  1., box->z1, p, q, r);
  1491. X
  1492. X    /* if result ended up in p2 then copy it to p1 */
  1493. X    if (p==&p2)
  1494. X    bcopy(&p2, p1, sizeof(Poly)-(POLY_NMAX-p2.n)*sizeof(Poly_vert));
  1495. X    return POLY_CLIP_PARTIAL;
  1496. X}
  1497. X
  1498. X/*
  1499. X * poly_clip_to_halfspace: clip convex polygon p against a plane,
  1500. X * copying the portion satisfying sign*s[index] < k*sw into q,
  1501. X * where s is a Poly_vert* cast as a double*.
  1502. X * index is an index into the array of doubles at each vertex, such that
  1503. X * s[index] is sx, sy, or sz (screen space x, y, or z).
  1504. X * Thus, to clip against xmin, use
  1505. X *    poly_clip_to_halfspace(p, q, XINDEX, -1., -xmin);
  1506. X * and to clip against xmax, use
  1507. X *    poly_clip_to_halfspace(p, q, XINDEX,  1.,  xmax);
  1508. X */
  1509. X
  1510. Xvoid poly_clip_to_halfspace(p, q, index, sign, k)
  1511. XPoly *p, *q;
  1512. Xregister int index;
  1513. Xdouble sign, k;
  1514. X{
  1515. X    register int m;
  1516. X    register double *up, *vp, *wp;
  1517. X    register Poly_vert *v;
  1518. X    int i;
  1519. X    Poly_vert *u;
  1520. X    double t, tu, tv;
  1521. X
  1522. X    q->n = 0;
  1523. X    q->mask = p->mask;
  1524. X
  1525. X    /* start with u=vert[n-1], v=vert[0] */
  1526. X    u = &p->vert[p->n-1];
  1527. X    tu = sign*COORD(u, index) - u->sw*k;
  1528. X    for (v= &p->vert[0], i=p->n; i>0; i--, u=v, tu=tv, v++) {
  1529. X    /* on old polygon (p), u is previous vertex, v is current vertex */
  1530. X    /* tv is negative if vertex v is in */
  1531. X    tv = sign*COORD(v, index) - v->sw*k;
  1532. X    if (tu<=0. ^ tv<=0.) {
  1533. X        /* edge crosses plane; add intersection point to q */
  1534. X        t = tu/(tu-tv);
  1535. X        up = (double *)u;
  1536. X        vp = (double *)v;
  1537. X        wp = (double *)&q->vert[q->n];
  1538. X        for (m=p->mask; m!=0; m>>=1, up++, vp++, wp++)
  1539. X        if (m&1) *wp = *up+t*(*vp-*up);
  1540. X        q->n++;
  1541. X    }
  1542. X    if (tv<=0.)        /* vertex v is in, copy it to q */
  1543. X        q->vert[q->n++] = *v;
  1544. X    }
  1545. X}
  1546. END_OF_FILE
  1547. if test 4217 -ne `wc -c <'PolyScan/poly_clip.c'`; then
  1548.     echo shar: \"'PolyScan/poly_clip.c'\" unpacked with wrong size!
  1549. fi
  1550. # end of 'PolyScan/poly_clip.c'
  1551. fi
  1552. if test -f 'PolyScan/poly_scan.c' -a "${1}" != "-c" ; then 
  1553.   echo shar: Will not clobber existing file \"'PolyScan/poly_scan.c'\"
  1554. else
  1555. echo shar: Extracting \"'PolyScan/poly_scan.c'\" \(4638 characters\)
  1556. sed "s/^X//" >'PolyScan/poly_scan.c' <<'END_OF_FILE'
  1557. X/*
  1558. X * Generic Convex Polygon Scan Conversion and Clipping
  1559. X * by Paul Heckbert
  1560. X * from "Graphics Gems", Academic Press, 1990
  1561. X */
  1562. X
  1563. X/*
  1564. X * poly_scan.c: point-sampled scan conversion of convex polygons
  1565. X *
  1566. X * Paul Heckbert    1985, Dec 1989
  1567. X */
  1568. X
  1569. X#include <stdio.h>
  1570. X#include <math.h>
  1571. X#include "poly.h"
  1572. X
  1573. X/*
  1574. X * poly_scan: Scan convert a polygon, calling pixelproc at each pixel with an
  1575. X * interpolated Poly_vert structure.  Polygon can be clockwise or ccw.
  1576. X * Polygon is clipped in 2-D to win, the screen space window.
  1577. X *
  1578. X * Scan conversion is done on the basis of Poly_vert fields sx and sy.
  1579. X * These two must always be interpolated, and only they have special meaning
  1580. X * to this code; any other fields are blindly interpolated regardless of
  1581. X * their semantics.
  1582. X *
  1583. X * The pixelproc subroutine takes the arguments:
  1584. X *
  1585. X *    pixelproc(x, y, point)
  1586. X *    int x, y;
  1587. X *    Poly_vert *point;
  1588. X *
  1589. X * All the fields of point indicated by p->mask will be valid inside pixelproc
  1590. X * except sx and sy.  If they were computed, they would have values
  1591. X * sx=x+.5 and sy=y+.5, since sampling is done at pixel centers.
  1592. X */
  1593. X
  1594. Xvoid poly_scan(p, win, pixelproc)
  1595. Xregister Poly *p;        /* polygon */
  1596. XWindow *win;            /* 2-D screen space clipping window */
  1597. Xvoid (*pixelproc)();        /* procedure called at each pixel */
  1598. X{
  1599. X    register int i, li, ri, y, ly, ry, top, rem, mask;
  1600. X    double ymin;
  1601. X    Poly_vert l, r, dl, dr;
  1602. X
  1603. X    if (p->n>POLY_NMAX) {
  1604. X    fprintf(stderr, "poly_scan: too many vertices: %d\n", p->n);
  1605. X    return;
  1606. X    }
  1607. X
  1608. X    ymin = HUGE;
  1609. X    for (i=0; i<p->n; i++)        /* find top vertex (y points down) */
  1610. X    if (p->vert[i].sy < ymin) {
  1611. X        ymin = p->vert[i].sy;
  1612. X        top = i;
  1613. X    }
  1614. X
  1615. X    li = ri = top;            /* left and right vertex indices */
  1616. X    rem = p->n;                /* number of vertices remaining */
  1617. X    y = ceil(ymin-.5);            /* current scan line */
  1618. X    ly = ry = y-1;            /* lower end of left & right edges */
  1619. X    mask = p->mask & ~POLY_MASK(sy);    /* stop interpolating screen y */
  1620. X
  1621. X    while (rem>0) {    /* scan in y, activating new edges on left & right */
  1622. X            /* as scan line passes over new vertices */
  1623. X
  1624. X    while (ly<=y && rem>0) {    /* advance left edge? */
  1625. X        rem--;
  1626. X        i = li-1;            /* step ccw down left side */
  1627. X        if (i<0) i = p->n-1;
  1628. X        incrementalize_y(&p->vert[li], &p->vert[i], &l, &dl, y, mask);
  1629. X        ly = floor(p->vert[i].sy+.5);
  1630. X        li = i;
  1631. X    }
  1632. X    while (ry<=y && rem>0) {    /* advance right edge? */
  1633. X        rem--;
  1634. X        i = ri+1;            /* step cw down right edge */
  1635. X        if (i>=p->n) i = 0;
  1636. X        incrementalize_y(&p->vert[ri], &p->vert[i], &r, &dr, y, mask);
  1637. X        ry = floor(p->vert[i].sy+.5);
  1638. X        ri = i;
  1639. X    }
  1640. X
  1641. X    while (y<ly && y<ry) {        /* do scanlines till end of l or r edge */
  1642. X        if (y>=win->y0 && y<=win->y1)
  1643. X        if (l.sx<=r.sx) scanline(y, &l, &r, win, pixelproc, mask);
  1644. X        else        scanline(y, &r, &l, win, pixelproc, mask);
  1645. X        y++;
  1646. X        increment(&l, &dl, mask);
  1647. X        increment(&r, &dr, mask);
  1648. X    }
  1649. X    }
  1650. X}
  1651. X
  1652. X/* scanline: output scanline by sampling polygon at Y=y+.5 */
  1653. X
  1654. Xstatic scanline(y, l, r, win, pixelproc, mask)
  1655. Xint y, mask;
  1656. XPoly_vert *l, *r;
  1657. XWindow *win;
  1658. Xvoid (*pixelproc)();
  1659. X{
  1660. X    int x, lx, rx;
  1661. X    Poly_vert p, dp;
  1662. X
  1663. X    mask &= ~POLY_MASK(sx);        /* stop interpolating screen x */
  1664. X    lx = ceil(l->sx-.5);
  1665. X    if (lx<win->x0) lx = win->x0;
  1666. X    rx = floor(r->sx-.5);
  1667. X    if (rx>win->x1) rx = win->x1;
  1668. X    if (lx>rx) return;
  1669. X    incrementalize_x(l, r, &p, &dp, lx, mask);
  1670. X    for (x=lx; x<=rx; x++) {        /* scan in x, generating pixels */
  1671. X    (*pixelproc)(x, y, &p);
  1672. X    increment(&p, &dp, mask);
  1673. X    }
  1674. X}
  1675. X
  1676. X/*
  1677. X * incrementalize_y: put intersection of line Y=y+.5 with edge between points
  1678. X * p1 and p2 in p, put change with respect to y in dp
  1679. X */
  1680. X
  1681. Xstatic incrementalize_y(p1, p2, p, dp, y, mask)
  1682. Xregister double *p1, *p2, *p, *dp;
  1683. Xregister int mask;
  1684. Xint y;
  1685. X{
  1686. X    double dy, frac;
  1687. X
  1688. X    dy = ((Poly_vert *)p2)->sy - ((Poly_vert *)p1)->sy;
  1689. X    if (dy==0.) dy = 1.;
  1690. X    frac = y+.5 - ((Poly_vert *)p1)->sy;
  1691. X
  1692. X    for (; mask!=0; mask>>=1, p1++, p2++, p++, dp++)
  1693. X    if (mask&1) {
  1694. X        *dp = (*p2-*p1)/dy;
  1695. X        *p = *p1+*dp*frac;
  1696. X    }
  1697. X}
  1698. X
  1699. X/*
  1700. X * incrementalize_x: put intersection of line X=x+.5 with edge between points
  1701. X * p1 and p2 in p, put change with respect to x in dp
  1702. X */
  1703. X
  1704. Xstatic incrementalize_x(p1, p2, p, dp, x, mask)
  1705. Xregister double *p1, *p2, *p, *dp;
  1706. Xregister int mask;
  1707. Xint x;
  1708. X{
  1709. X    double dx, frac;
  1710. X
  1711. X    dx = ((Poly_vert *)p2)->sx - ((Poly_vert *)p1)->sx;
  1712. X    if (dx==0.) dx = 1.;
  1713. X    frac = x+.5 - ((Poly_vert *)p1)->sx;
  1714. X
  1715. X    for (; mask!=0; mask>>=1, p1++, p2++, p++, dp++)
  1716. X    if (mask&1) {
  1717. X        *dp = (*p2-*p1)/dx;
  1718. X        *p = *p1+*dp*frac;
  1719. X    }
  1720. X}
  1721. X
  1722. Xstatic increment(p, dp, mask)
  1723. Xregister double *p, *dp;
  1724. Xregister int mask;
  1725. X{
  1726. X    for (; mask!=0; mask>>=1, p++, dp++)
  1727. X    if (mask&1)
  1728. X        *p += *dp;
  1729. X}
  1730. END_OF_FILE
  1731. if test 4638 -ne `wc -c <'PolyScan/poly_scan.c'`; then
  1732.     echo shar: \"'PolyScan/poly_scan.c'\" unpacked with wrong size!
  1733. fi
  1734. # end of 'PolyScan/poly_scan.c'
  1735. fi
  1736. if test -f 'Roots3And4.c' -a "${1}" != "-c" ; then 
  1737.   echo shar: Will not clobber existing file \"'Roots3And4.c'\"
  1738. else
  1739. echo shar: Extracting \"'Roots3And4.c'\" \(4127 characters\)
  1740. sed "s/^X//" >'Roots3And4.c' <<'END_OF_FILE'
  1741. X/*
  1742. X *  Roots3And4.c
  1743. X *
  1744. X *  Utility functions to find cubic and quartic roots,
  1745. X *  coefficients are passed like this:
  1746. X *
  1747. X *      c[0] + c[1]*x + c[2]*x^2 + c[3]*x^3 + c[4]*x^4 = 0
  1748. X *
  1749. X *  The functions return the number of non-complex roots and
  1750. X *  put the values into the s array.
  1751. X *
  1752. X *  Author:         Jochen Schwarze (schwarze@isa.de)
  1753. X *
  1754. X *  Jan 26, 1990    Version for Graphics Gems
  1755. X *  Oct 11, 1990    Fixed sign problem for negative q's in SolveQuartic
  1756. X *                  (reported by Mark Podlipec),
  1757. X *                  Old-style function definitions,
  1758. X *                  IsZero() as a macro
  1759. X */
  1760. X
  1761. X#include    <math.h>
  1762. X
  1763. X/* epsilon surrounding for near zero values */
  1764. X
  1765. X#define     EQN_EPS     1e-9
  1766. X#define        IsZero(x)    ((x) > -EQN_EPS && (x) < EQN_EPS)
  1767. X
  1768. X
  1769. Xint SolveQuadric(c, s)
  1770. X    double c[ 3 ];
  1771. X    double s[ 2 ];
  1772. X{
  1773. X    double p, q, D;
  1774. X
  1775. X    /* normal form: x^2 + px + q = 0 */
  1776. X
  1777. X    p = c[ 1 ] / (2 * c[ 2 ]);
  1778. X    q = c[ 0 ] / c[ 2 ];
  1779. X
  1780. X    D = p * p - q;
  1781. X
  1782. X    if (IsZero(D))
  1783. X    {
  1784. X    s[ 0 ] = - p;
  1785. X    return 1;
  1786. X    }
  1787. X    else if (D < 0)
  1788. X    {
  1789. X    return 0;
  1790. X    }
  1791. X    else if (D > 0)
  1792. X    {
  1793. X    double sqrt_D = sqrt(D);
  1794. X
  1795. X    s[ 0 ] =   sqrt_D - p;
  1796. X    s[ 1 ] = - sqrt_D - p;
  1797. X    return 2;
  1798. X    }
  1799. X}
  1800. X
  1801. X
  1802. Xint SolveCubic(c, s)
  1803. X    double c[ 4 ];
  1804. X    double s[ 3 ];
  1805. X{
  1806. X    int     i, num;
  1807. X    double  sub;
  1808. X    double  A, B, C;
  1809. X    double  sq_A, p, q;
  1810. X    double  cb_p, D;
  1811. X
  1812. X    /* normal form: x^3 + Ax^2 + Bx + C = 0 */
  1813. X
  1814. X    A = c[ 2 ] / c[ 3 ];
  1815. X    B = c[ 1 ] / c[ 3 ];
  1816. X    C = c[ 0 ] / c[ 3 ];
  1817. X
  1818. X    /*  substitute x = y - A/3 to eliminate quadric term:
  1819. X    x^3 +px + q = 0 */
  1820. X
  1821. X    sq_A = A * A;
  1822. X    p = 1.0/3 * (- 1.0/3 * sq_A + B);
  1823. X    q = 1.0/2 * (2.0/27 * A * sq_A - 1.0/3 * A * B + C);
  1824. X
  1825. X    /* use Cardano's formula */
  1826. X
  1827. X    cb_p = p * p * p;
  1828. X    D = q * q + cb_p;
  1829. X
  1830. X    if (IsZero(D))
  1831. X    {
  1832. X    if (IsZero(q)) /* one triple solution */
  1833. X    {
  1834. X        s[ 0 ] = 0;
  1835. X        num = 1;
  1836. X    }
  1837. X    else /* one single and one double solution */
  1838. X    {
  1839. X        double u = cbrt(-q);
  1840. X        s[ 0 ] = 2 * u;
  1841. X        s[ 1 ] = - u;
  1842. X        num = 2;
  1843. X    }
  1844. X    }
  1845. X    else if (D < 0) /* Casus irreducibilis: three real solutions */
  1846. X    {
  1847. X    double phi = 1.0/3 * acos(-q / sqrt(-cb_p));
  1848. X    double t = 2 * sqrt(-p);
  1849. X
  1850. X    s[ 0 ] =   t * cos(phi);
  1851. X    s[ 1 ] = - t * cos(phi + M_PI / 3);
  1852. X    s[ 2 ] = - t * cos(phi - M_PI / 3);
  1853. X    num = 3;
  1854. X    }
  1855. X    else /* one real solution */
  1856. X    {
  1857. X    double sqrt_D = sqrt(D);
  1858. X    double u = cbrt(sqrt_D - q);
  1859. X    double v = - cbrt(sqrt_D + q);
  1860. X
  1861. X    s[ 0 ] = u + v;
  1862. X    num = 1;
  1863. X    }
  1864. X
  1865. X    /* resubstitute */
  1866. X
  1867. X    sub = 1.0/3 * A;
  1868. X
  1869. X    for (i = 0; i < num; ++i)
  1870. X    s[ i ] -= sub;
  1871. X
  1872. X    return num;
  1873. X}
  1874. X
  1875. X
  1876. Xint SolveQuartic(c, s)
  1877. X    double c[ 5 ]; 
  1878. X    double s[ 4 ];
  1879. X{
  1880. X    double  coeffs[ 4 ];
  1881. X    double  z, u, v, sub;
  1882. X    double  A, B, C, D;
  1883. X    double  sq_A, p, q, r;
  1884. X    int     i, num;
  1885. X
  1886. X    /* normal form: x^4 + Ax^3 + Bx^2 + Cx + D = 0 */
  1887. X
  1888. X    A = c[ 3 ] / c[ 4 ];
  1889. X    B = c[ 2 ] / c[ 4 ];
  1890. X    C = c[ 1 ] / c[ 4 ];
  1891. X    D = c[ 0 ] / c[ 4 ];
  1892. X
  1893. X    /*  substitute x = y - A/4 to eliminate cubic term:
  1894. X    x^4 + px^2 + qx + r = 0 */
  1895. X
  1896. X    sq_A = A * A;
  1897. X    p = - 3.0/8 * sq_A + B;
  1898. X    q = 1.0/8 * sq_A * A - 1.0/2 * A * B + C;
  1899. X    r = - 3.0/256*sq_A*sq_A + 1.0/16*sq_A*B - 1.0/4*A*C + D;
  1900. X
  1901. X    if (IsZero(r))
  1902. X    {
  1903. X    /* no absolute term: y(y^3 + py + q) = 0 */
  1904. X
  1905. X    coeffs[ 0 ] = q;
  1906. X    coeffs[ 1 ] = p;
  1907. X    coeffs[ 2 ] = 0;
  1908. X    coeffs[ 3 ] = 1;
  1909. X
  1910. X    num = SolveCubic(coeffs, s);
  1911. X
  1912. X    s[ num++ ] = 0;
  1913. X    }
  1914. X    else
  1915. X    {
  1916. X    /* solve the resolvent cubic ... */
  1917. X
  1918. X    coeffs[ 0 ] = 1.0/2 * r * p - 1.0/8 * q * q;
  1919. X    coeffs[ 1 ] = - r;
  1920. X    coeffs[ 2 ] = - 1.0/2 * p;
  1921. X    coeffs[ 3 ] = 1;
  1922. X
  1923. X    (void) SolveCubic(coeffs, s);
  1924. X
  1925. X    /* ... and take the one real solution ... */
  1926. X
  1927. X    z = s[ 0 ];
  1928. X
  1929. X    /* ... to build two quadric equations */
  1930. X
  1931. X    u = z * z - r;
  1932. X    v = 2 * z - p;
  1933. X
  1934. X    if (IsZero(u))
  1935. X        u = 0;
  1936. X    else if (u > 0)
  1937. X        u = sqrt(u);
  1938. X    else
  1939. X        return 0;
  1940. X
  1941. X    if (IsZero(v))
  1942. X        v = 0;
  1943. X    else if (v > 0)
  1944. X        v = sqrt(v);
  1945. X    else
  1946. X        return 0;
  1947. X
  1948. X    coeffs[ 0 ] = z - u;
  1949. X    coeffs[ 1 ] = q < 0 ? -v : v;
  1950. X    coeffs[ 2 ] = 1;
  1951. X
  1952. X    num = SolveQuadric(coeffs, s);
  1953. X
  1954. X    coeffs[ 0 ]= z + u;
  1955. X    coeffs[ 1 ] = q < 0 ? v : -v;
  1956. X    coeffs[ 2 ] = 1;
  1957. X
  1958. X    num += SolveQuadric(coeffs, s + num);
  1959. X    }
  1960. X
  1961. X    /* resubstitute */
  1962. X
  1963. X    sub = 1.0/4 * A;
  1964. X
  1965. X    for (i = 0; i < num; ++i)
  1966. X    s[ i ] -= sub;
  1967. X
  1968. X    return num;
  1969. X}
  1970. X
  1971. END_OF_FILE
  1972. if test 4127 -ne `wc -c <'Roots3And4.c'`; then
  1973.     echo shar: \"'Roots3And4.c'\" unpacked with wrong size!
  1974. fi
  1975. # end of 'Roots3And4.c'
  1976. fi
  1977. echo shar: End of archive 3 \(of 5\).
  1978. cp /dev/null ark3isdone
  1979. MISSING=""
  1980. for I in 1 2 3 4 5 ; do
  1981.     if test ! -f ark${I}isdone ; then
  1982.     MISSING="${MISSING} ${I}"
  1983.     fi
  1984. done
  1985. if test "${MISSING}" = "" ; then
  1986.     echo You have unpacked all 5 archives.
  1987.     rm -f ark[1-9]isdone
  1988. else
  1989.     echo You still need to unpack the following archives:
  1990.     echo "        " ${MISSING}
  1991. fi
  1992. ##  End of shell archive.
  1993. exit 0
  1994.  
  1995.